﻿using System;
using System.IO;
using System.Diagnostics;
using System.Security.AccessControl;
using System.Text;

namespace BackupLibrary
{
    public class BackupProcess
    {

        public static bool BackupNow(Job job)
        {
            try
            {
                String path = System.Reflection.Assembly.GetExecutingAssembly().Location;
                path = System.IO.Path.GetDirectoryName(path);

                if (!Directory.Exists(path + "\\Backup"))
                {
                    DirectorySecurity sec = new DirectorySecurity();
                    sec.CreateDir(path + "\\Backup", "Everyone");
                    sec.CreateDir(path + "\\Backup", "Administrators");
                    sec.CreateDir(path + "\\Backup", "Local Service");
                }

                if (Directory.Exists(path + "\\Backup"))
                {
                    string fileName = string.Format("{3}_Backup_{0}_{1}_{2}.BAK", DateTime.Now.Day.ToString("00"), DateTime.Now.Month.ToString("00"), DateTime.Now.Year.ToString("0000"), job.Database);
                    string fullFileName = path + "\\Backup\\" + fileName;

                    if (!File.Exists(fullFileName))
                    {
                        Database db = new Database();
                        db.BackupDb(job, fullFileName);
                    }

                    if (File.Exists(fullFileName))
                    {

                        if (job.Type == Job.BackupTypes.Folder)
                        {
                            string localfile = fullFileName;
                            if (job.doCompress)
                            {
                                localfile = ZipFile(fullFileName, Settings.Get.WinrarPath);
                            }

                            if (Directory.Exists(job.Folder) && File.Exists(localfile))
                            {
                                File.Copy(localfile, job.Folder + "\\" + fileName.Remove(fileName.Length - 3, 3) + "RAR", true);
                            }
                        }
                        else
                        {
                            string localfile = fullFileName;

                            if (job.doCompress)
                            {
                                localfile = ZipFile(fullFileName, Settings.Get.WinrarPath);
                            }

                            FtpUtil ftp = new FtpUtil(job.FtpServer, job.FtpUser, job.FtpPassword);
                            ftp.Upload(job.FtpFolder, localfile);

                            Settings.Get.AddLog(new LogEntry()
                            {
                                Database = job.Database,
                                Date = DateTime.Now,
                                Message = "Ftp Gönderildi !",
                                Server = job.Server
                            });
                        }

                        job.LastExecuteDate = DateTime.Now;
                        SendEmail(job, true, "");
                        RemoveExpiresBackup(job);
                    }
                    else
                    {
                        SendEmail(job, false, "Veritabanı yedek alınamadı !");
                    }
                }
                return true;
            }
            catch (Exception ex)
            {
                Settings.Get.AddLog(new LogEntry()
                {
                    Database = job.Database,
                    Date = DateTime.Now,
                    Message = ex.Message,
                    Server = job.Server
                });

                SendEmail(job, false, ex.Message);
                return false;
            }
        }

        private static void SendEmail(Job job, bool state, string errorMesasage)
        {
            EmailProcess mail = new EmailProcess();
            StringBuilder sb = new StringBuilder();
            sb.AppendFormat("Tarih:{0}", DateTime.Now.ToLongDateString());
            sb.Append("\r\n");
            sb.AppendFormat("Veritabanı:{0}", job.Database);
            sb.Append("\r\n");
            sb.AppendFormat("Sunucu:{0}", job.Server);
            sb.Append("\r\n");
            if (state)
            {
                sb.AppendFormat("İşlem:Başarılı!");
                sb.Append("\r\n");
                sb.AppendFormat("Mesaj:{0}", Settings.Get.Message);
                sb.Append("\r\n");
            }
            else
            {
                sb.AppendFormat("İşlem:Başarısız Yedek Alınamadı!");
                sb.Append("\r\n");
                sb.AppendFormat("Hata Mesajı:{0}", errorMesasage);
                sb.Append("\r\n");
            }

            if (Settings.Get.AccountType == "Gmail")
            {
                mail.GmailMailGonder(Settings.Get.SenderMailAdress, Settings.Get.EmailAdress, Settings.Get.UserId, Settings.Get.Password, "Yedekleme", sb.ToString(), Settings.Get.ServerAddress);
            }
            else
            {
                mail.PopMailGonder(Settings.Get.SenderMailAdress, Settings.Get.EmailAdress, Settings.Get.UserId, Settings.Get.Password, "Yedekleme", sb.ToString(), Settings.Get.ServerAddress);
            }
        }

        private static string ZipFile(string fileName, string winrarPath)
        {
            string rarfile = "";
            if (File.Exists(winrarPath) && File.Exists(fileName))
            {
                rarfile = fileName.Remove(fileName.Length - 3, 3) + "RAR";
                ProcessStartInfo info = new ProcessStartInfo(winrarPath, " a \"" + rarfile + "\" \"" + fileName + "\"");
                info.CreateNoWindow = true;
                info.WindowStyle = ProcessWindowStyle.Hidden;
                Process p = Process.Start(info);
                p.WaitForExit();
            }

            if (File.Exists(rarfile))
            {
                File.Delete(fileName);
                return rarfile;
            }
            else
            {
                return "";
            }
        }

        private static void RemoveExpiresBackup(Job job)
        {
            String path = System.Reflection.Assembly.GetExecutingAssembly().Location;
            path = System.IO.Path.GetDirectoryName(path);

            if (Directory.Exists(path + "\\Backup"))
            {
                string[] removeRarfiles = Directory.GetFiles(path + "\\Backup", "*.rar", SearchOption.TopDirectoryOnly);
                string[] removeBakfiles = Directory.GetFiles(path + "\\Backup", "*.BAK", SearchOption.TopDirectoryOnly);

                FtpUtil ftp = new FtpUtil(job.FtpServer, job.FtpUser, job.FtpPassword);
                foreach (string file in removeRarfiles)
                {
                    FileInfo finfo = new FileInfo(file);
                    if (finfo.CreationTime < DateTime.Now.AddDays(-1 * job.MaxExpireDays))
                    {
                        File.Delete(file);

                        if (job.Type == Job.BackupTypes.Ftp && ftp != null)
                        {
                            ftp.DeleteFTP(job.FtpFolder + "/" + finfo.Name);
                        }
                    }
                }

                foreach (string file in removeBakfiles)
                {
                    if (File.GetCreationTime(file) < DateTime.Now.AddDays(-1 * job.MaxExpireDays))
                    {
                        File.Delete(file);
                    }
                }
            }
        }

    }
}
